﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using StructureModelDeduction.Data;
using StructureModelDeduction.Forms;
using StructureModelDeduction.Kit;

namespace StructureModelDeduction.Manager
{
	public class ModelDeductionManager
	{
		public ModelDeductionManager(ExternalCommandData commandData)
		{
			this.m_cmdData = commandData;
			this.m_uiDoc = commandData.Application.ActiveUIDocument;
			this.m_doc = this.m_uiDoc.Document;
		}

		public bool Run()
		{
			int selLinkInstance = this.GetSelLinkInstance();
			if ((selLinkInstance == 1 && this.m_lstSelLinkInstance.Count == 0) || selLinkInstance == 0)
			{
				YJKMessageBox.Show("没有可以进行扣减的链接文件!");
				return false;
			}
			if (selLinkInstance == 2)
			{
				return false;
			}
			this.GetIntersecInformation();
			Dictionary<ElementDataPack, List<ElementDataPack>> dictionary = new Dictionary<ElementDataPack, List<ElementDataPack>>();
			Dictionary<ElementDataPack, List<ElementDataPack>> dicDeductionColumn = new Dictionary<ElementDataPack, List<ElementDataPack>>();
			foreach (IntersectionInformGetterForColumn informGetter in this.m_lstIntersectForColumn)
			{
				this.GetDisplayInformation(ref dictionary, ref dicDeductionColumn, informGetter);
			}
			Dictionary<ElementDataPack, List<ElementDataPack>> dictionary2 = new Dictionary<ElementDataPack, List<ElementDataPack>>();
			Dictionary<ElementDataPack, List<ElementDataPack>> dicDeductionWall = new Dictionary<ElementDataPack, List<ElementDataPack>>();
			foreach (IntersectionInformGetterForWall informGetter2 in this.m_lstIntersectForWall)
			{
				this.GetDisplayInformation(ref dictionary2, ref dicDeductionWall, informGetter2);
			}
			if (dictionary2.Count == 0 && dictionary.Count == 0)
			{
				return DeductionKit.DeductionWallAndColumn(this.m_doc, dicDeductionWall, dicDeductionColumn);
			}
			return this.ShowResultAndDeduction(dictionary, dicDeductionColumn, dictionary2, dicDeductionWall);
		}

		private bool ShowResultAndDeduction(Dictionary<ElementDataPack, List<ElementDataPack>> dicDisplayColumn, Dictionary<ElementDataPack, List<ElementDataPack>> dicDeductionColumn, Dictionary<ElementDataPack, List<ElementDataPack>> dicDisplayWall, Dictionary<ElementDataPack, List<ElementDataPack>> dicDeductionWall)
		{
			DeductionForm deductionForm = new DeductionForm(this.m_uiDoc, dicDeductionWall, dicDeductionColumn, dicDisplayWall, dicDisplayColumn);
			deductionForm.Show(CmdStructuralModelDeduction._hWndRevit);
			try
			{
				for (;;)
				{
					this.m_uiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
				}
			}
			catch (Exception ex)
			{
                if (!(ex is Autodesk.Revit.Exceptions.OperationCanceledException))
				{
					return false;
				}
				deductionForm.Close();
			}
			return true;
		}

		public bool GetIntersecInformation()
		{
			foreach (ElementId linkDocId in this.m_lstSelLinkInstance)
			{
				LinkDocPacker linkDocPacker = new LinkDocPacker(this.m_cmdData, this.m_doc, linkDocId);
				linkDocPacker.GetLinkDocInform();
				foreach (ColumnDataPack elemData in linkDocPacker.LstColumnData)
				{
					IntersectionInformGetterForColumn intersectionInformGetterForColumn = new IntersectionInformGetterForColumn(this.m_doc, elemData, this.m_cmdData);
					intersectionInformGetterForColumn.CheckRelationType();
					this.m_lstIntersectForColumn.Add(intersectionInformGetterForColumn);
				}
				foreach (WallDataPack elemData2 in linkDocPacker.LstWallData)
				{
					IntersectionInformGetterForWall intersectionInformGetterForWall = new IntersectionInformGetterForWall(this.m_doc, elemData2);
					intersectionInformGetterForWall.CheckRelationType();
					this.m_lstIntersectForWall.Add(intersectionInformGetterForWall);
				}
			}
			return true;
		}

		public void GetDisplayInformation(ref Dictionary<ElementDataPack, List<ElementDataPack>> dicDisplay, ref Dictionary<ElementDataPack, List<ElementDataPack>> dicDeduction, IntersectionInformGetter InformGetter)
		{
			if (InformGetter.lstDisplay.Count > 0)
			{
				dicDisplay.Add(InformGetter.ElementData, InformGetter.lstDisplay);
			}
			if (InformGetter.lstDeduction.Count > 0)
			{
				dicDeduction.Add(InformGetter.ElementData, InformGetter.lstDeduction);
			}
			if (InformGetter.lstDisplay.Count == 0 && InformGetter.lstDeduction.Count == 0)
			{
				dicDisplay.Add(InformGetter.ElementData, null);
			}
		}

		public List<ElementId> GetLinkInstace()
		{
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(RevitLinkInstance));
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.WherePasses(elementClassFilter).WhereElementIsNotElementType().ToElementIds();
			List<ElementId> list = new List<ElementId>();
			foreach (Element element in filteredElementCollector)
			{
				RevitLinkInstance revitLinkInstance = element as RevitLinkInstance;
				if (revitLinkInstance.GetLinkDocument() != null)
				{
					list.Add(element.Id);
				}
			}
			return list;
		}

		private int GetSelLinkInstance()
		{
			List<ElementId> linkInstace = this.GetLinkInstace();
			if (linkInstace.Count == 0)
			{
				return 0;
			}
			LinkInstanceListForm linkInstanceListForm = new LinkInstanceListForm(linkInstace, this.m_doc);
			if (linkInstanceListForm.ShowDialog() == DialogResult.OK)
			{
				this.m_lstSelLinkInstance = linkInstanceListForm.LstLinkId;
				return 1;
			}
			return 2;
		}

		private List<IntersectionInformGetterForColumn> m_lstIntersectForColumn = new List<IntersectionInformGetterForColumn>();

		private List<IntersectionInformGetterForWall> m_lstIntersectForWall = new List<IntersectionInformGetterForWall>();

		private List<ElementId> m_lstSelLinkInstance = new List<ElementId>();

		private UIDocument m_uiDoc;

		private Document m_doc;

		private ExternalCommandData m_cmdData;
	}
}
